<?php
// +----------------------------------------------------------------------
// | 附件上传（图片，文件上传）
// +----------------------------------------------------------------------
// | Copyright (c) 2015
// +----------------------------------------------------------------------
// | Author: baiping 125618036@qq.com http://www.webipcode.com
// +----------------------------------------------------------------------
// |2015-11-26 上午10:46:40
// +----------------------------------------------------------------------
defined('BASEPATH') OR exit('No direct script access allowed');

class File extends MY_Controller{
	
	private $rootPath; //站点路径
// 	private $error ='' ;//错误信息
	private $public_dir;
	
	public function __construct(){
		parent::__construct();
		$this->rootPath = FCPATH;
		$this->public_dir = 'Uploads';
// 		$this->error = '';
	}
	
	/**
	 * 获取最后一次上传错误信息
	 * @return string 错误信息
	 */
	public function Error(){
		return $this->error;
	}
	/**
	 * 上传图片
	 */
	public function uploadPicture(){
		/* 返回标准数据 */
		$return  = array('status' => 1, 'info' => '上传成功');
		if ( IS_POST ){
			//接受参数
			$file_element_name= 'userfile';
			$defind_save_path = $this->input->post('save_path',true);//自定义保存路径
			$is_thumb         = $this->input->post('is_thumb',true);//是否生成缩略图,默认值为１
			$thumb_m_width    = $this->input->post('thumb_m_width');
			$is_thumb         = $this->input->post('is_thumb');
			$thumb_m_height   = $this->input->post('thumb_m_height');
			$thumb_m_width    = empty( $thumb_m_width ) ? config_item('thumb_m_width') : $thumb_m_width;//中图缩略图的宽度
			$thumb_m_height   = empty( $thumb_m_height ) ? config_item('thumb_m_height') : $thumb_m_height;//中图缩略图的高度
			$is_thumb         = empty( $is_thumb ) ? config_item('is_thumb') : $is_thumb;//是否缩略图处理
			//
			
			$upload_path = $this->rootPath . $this->public_dir .'/'.$defind_save_path;
			//检测上传根目录
			if ( !$this->checkRootPath( $this->rootPath ) ){
				$return['status'] = 0;
				$return['info'] = $this->error;
			}
			//检测上传目录
			if ( !$this->checkSavePath($upload_path) ){
				$return['status'] = 0;
				$return['info'] = $this->error;
			}
			
			/* 逐个检测文件 */
			if(function_exists('finfo_open')){
				$finfo   =  finfo_open ( FILEINFO_MIME_TYPE );
			}
			// 对上传文件数组信息处理,如果图片已经存在，则直接返回数据库中保存的数据，否则上传
			$files   =  $this->dealFiles($_FILES);
			$data = $this->checkFiles($files);
			if ( $data ){
				$return['status'] = 1;
				$return['info'] = '上传成功';
				$return['data'] = $data;//返回已经存在的图片信息
				echo json_encode( $return );
				exit;
			}

			$config['upload_path']   = $upload_path;
			$config['allowed_types'] = 'gif|jpg|png|jpeg';//允许上传的图片后缀
			$config['file_name']     = date('YmdHis', time()).rand(1000, 9999);//新建文件名
			$config['max_size']      = '2048';
			$config['max_width']     = '1024';
			$config['max_height']    = '768';
			$config['encrypt_name']  = true;//转换文件的后缀为小写
			$config['file_ext_tolower']  = true;//转换文件的后缀为小写
			$config['remove_spaces'] = true;//文件名中的所有空格将转换为下划线
			$this->load->library('upload', $config);//加载上传类
			
			if ( !$this->upload->do_upload($file_element_name)){
				$return['status'] = 0;
				$return['info'] = $this->upload->display_errors();
			}else{
				$data = $this->upload->data();
				//入库并返回数据到前台
				$search_path =  str_replace("\\","/",$this->rootPath.$this->public_dir.'/');
				$file_path = str_replace($search_path, '', $data['full_path']);
				$insert_data['path'] = $file_path;
				$insert_data['md5'] = md5_file($data['full_path']);
				$insert_data['sha1'] = sha1_file($data['full_path']);
				$insert_data['create_time'] = time();
				$this->load->model('Picture_model', 'pic');//实例化图片模型
				$insert_id = $this->pic->addData( $insert_data );//入库
				if ( $insert_id ){
					$data['path'] = $file_path;
					$data['id'] = $insert_id;
					$return['status'] = 1;
					$return['data'] = $data;
				}
			}
			echo json_encode( $return );
			exit;
		}else{
			$return['status'] = '0';
			$return['info'] = '非法请求';
			return $return;
		}
	}
	
	/**
	 * 检测上传图片是 否合法，并检测在数据库中是否存在
	 */
	private function checkFiles($files){
		foreach ($files as $key => $file) {
			$file['name']  = strip_tags($file['name']);
			if(!isset($file['key']))   $file['key']    =   $key;
			/* 文件上传检测 */
			if (!$this->check($file)){
				return $this->error;
				continue;
			}
			/* 获取文件hash */
			$file['md5']  = md5_file($file['tmp_name']);
			$file['sha1'] = sha1_file($file['tmp_name']);
			/* 调用回调函数检测文件是否存在 */
			$data = $this->getPicture($file['md5'], $file['sha1']);
			if( $data ){
				if ( file_exists($this->rootPath . $this->public_dir.'/'.$data['path'])  ) {
					$return['data'] = $data;
					continue;
				}else{
					//删除垃圾数据
					$this->load->model('Picture_model', 'pic');//加载图片管理模型
					$this->pic->deleteData( array('md5'=>$file['md5'], 'sha1'=>$file['sha1']) );
				}
			}
		}
		return $data;
	}
	
	/**
	 * 获取当前上传的图片是否已经在数据库中存在（通过获取图片的md5唯一值）
	 * @param unknown_type $md5_file
	 * @param unknown_type $sha1_file
	 */
	private function getPicture($md5_file, $sha1_file){
		$this->load->model('Picture_model', 'pic');//加载图片管理模型
		$res = $this->pic->getFind( array('md5'=>$md5_file, 'sha1'=>$sha1_file) );
		return $res;
	}
	
	/**
	 * 转换上传文件数组变量为正确的方式
	 * @access private
	 * @param array $files  上传的文件变量
	 * @return array
	 */
	private function dealFiles($files) {
		$fileArray  = array();
		$n          = 0;
		foreach ($files as $key=>$file){
			if(is_array($file['name'])) {
				$keys       =   array_keys($file);
				$count      =   count($file['name']);
				for ($i=0; $i<$count; $i++) {
					$fileArray[$n]['key'] = $key;
					foreach ($keys as $_key){
						$fileArray[$n][$_key] = $file[$_key][$i];
					}
					$n++;
				}
			}else{
				$fileArray = $files;
				break;
			}
		}
		return $fileArray;
	}
	
	/**
	 * 检查上传的文件
	 * @param array $file 文件信息
	 */
	private function check($file) {
		/* 文件上传失败，捕获错误代码 */
		if ($file['error']) {
			$this->error($file['error']);
			return false;
		}
	
		/* 无效上传 */
		if (empty($file['name'])){
			$this->error = '未知上传错误！';
		}
	
		/* 检查是否合法上传 */
		if (!is_uploaded_file($file['tmp_name'])) {
			$this->error = '非法上传文件！';
			return false;
		}
		/* 通过检测 */
		return true;
	}
	
	/**
	 * 检查文件大小是否合法
	 * @param integer $size 数据
	 */
	private function checkSize($size) {
		return !($size > $this->maxSize) || (0 == $this->maxSize);
	}
	
	
	/**
	 * 检测上传目录
	 * @param  string $savepath 上传目录
	 * @return boolean          检测结果，true-通过，false-失败
	 */
	function checkSavePath($savepath){
		/* 检测并创建目录 */
		if ( !is_dir( $savepath ) ){
			if (!mkdir($savepath)) {
				return false;
			} else {
				/* 检测目录是否可写 */
				if (!is_writable($savepath)) {
					$this->error = '上传目录 ' . $savepath . ' 不可写！';
					return false;
				} else {
					return true;
				}
			}
		}	
	}
	
	/**
	 * 检测上传根目录
	 * @param string $rootpath   根目录
	 * @return boolean true-检测通过，false-检测失败
	 */
	public function checkRootPath($rootpath){
		if(!(is_dir($rootpath) && is_writable($rootpath))){
			$this->error = '上传根目录不存在！请尝试手动创建:'.$rootpath;
			return false;
		}
		$this->rootPath = $rootpath;
		return true;
	}
	
	
	
}